﻿#pragma once

#include <chrono>

#include "core/Macro.h"
#include "function/WindowSystem/AbstractWindow.h"
#include "function/LayerSystem/Layer.h"
#include "function/LayerSystem/LayerStack.h"
#include "function/LayerSystem/ImGui/ImGuiLayer.h"
#include "function/EventSystem/ApplicationEvent.h"
#include "function/RenderSystem/AbstractBuffer.h"

namespace Engine
{
	class ENGINE_API GameEngine final
	{
	public:
		GameEngine();
		~GameEngine();

		[[nodiscard]] float CalculateDeltaTime();
		void CalculateFPS(float deltaTime);
		bool TickOneFrame(float deltaTime);

		void OnEvent(Event& event);

		void PushLayer(Layer* layer);
		void PushOverlay(Layer* layer);

		static GameEngine& GetInstance(){ return *instance; }
		[[nodiscard]] AbstractWindow& GetWindow() const { return *window; }
		
	private:
		static GameEngine* instance;

		void TickLogic(float deltaTime);
		void TickRender(float deltaTime);
		std::chrono::steady_clock::time_point lastFrameTime{ std::chrono::steady_clock::now() };
		int fps = 0;

		Scope<AbstractWindow> window;
		bool OnWindowClose(WindowCloseEvent& event);
		bool shouldClose = false;

		LayerStack layerStack;
		ImGuiLayer* imGuiLayer;
	};
}
